﻿using System;
using System.Linq;
using System.Windows.Threading;
using PersonaLibrary.PersonaliiReference;
using PersonaLibrary.View;

namespace PersonaLibrary.ViewModel.OrganizationViewModel
{
	internal class OrganizationViewModel : ReferenceEditableItem<Organization>
    {
    	private RelayCommand _addNewDepartment;
		private RelayCommand _addParentCommand;
		private RelayCommand _deleteParentCommand;
		private Organization _parent;

        public OrganizationViewModel(int id)
        {
        	EditableItem = Context.TryCreateAndExecuteQuery<Organization>(string.Format("Organization?$filter=Id eq {0}", id), 
				"Не удалось загрузить организацию").FirstOrDefault();
        	IsDepartmentLoad = true;
			RisePropertyChanged("IsDepartmentLoad");
        	Context.BeginLoadProperty(EditableItem, "Department", EndLoadDepartments, null);
        }

        public OrganizationViewModel()
        {
            EditableItem = new Organization();
        }


        #region Public properties

		public Organization Parent
		{
			get
			{
				if (_parent == null && EditableItem.ParentOrganization.HasValue)
					_parent = Context.TryCreateAndExecuteQuery<Organization>(string.Format("Organization?$filter=Id eq {0}", EditableItem.ParentOrganization.Value),
						"Не удалось загрузить вышестоящую организацию").First();

				return _parent;
			}
		}

    	public RelayCommand AddNewDepartment
    	{
    		get
    		{
				if(_addNewDepartment == null)
					_addNewDepartment = new RelayCommand(x => AddNewDepartmentMethod(), x => true);
    			return _addNewDepartment;
    		}
    	}

		public RelayCommand AddParentCommand
		{
			get
			{
				if(_addParentCommand == null)
					_addParentCommand = new RelayCommand(x => AddParent(), x => true);
				return _addParentCommand;
			}
		}

		public RelayCommand DeleteParentCommand
		{
			get
			{
				if(_deleteParentCommand == null)
					_deleteParentCommand = new RelayCommand(x => DeleteParent(), x => true);
				return _deleteParentCommand;
			}
		}

		public bool IsDepartmentLoad { set; get; }

		#endregion

		private void DeleteParent()
		{
			EditableItem.ParentOrganization = null;
			_parent = null;
			RisePropertyChanged("Parent");
		}

		private void AddParent()
		{
			var selectedOrgs = Context.TryCreateAndExecuteQuery<Organization>("Organization?$select=Id,Name", "Не удалось загрузить cписок организаций");
			SelectFromCollection selectFrom = new SelectFromCollection
			                                  	{Values = selectedOrgs.ToDictionary(x => x.Name, x => x.Id)};
			if (selectFrom.ShowDialog().GetValueOrDefault())
			{
				EditableItem.ParentOrganization = (int)selectFrom.SelectedValue;
				RisePropertyChanged("Parent");
			}
		}

		private void AddNewDepartmentMethod()
		{
			if (EditableItem.Id == 0)
			{
				CurrentApplication.ShowMessage("Невозможно добавить отдел к организации которой нет в базе. Сохраните организацию и попробуйте снова.");
			}
			else
			{
				Department newDepartment = new Department {Organization = EditableItem, OrganizationId = EditableItem.Id};
				EditableItem.Department.Insert(0, newDepartment);
				Context.AddObject(typeof (Department).Name, newDepartment);
			}
		}

		private void EndLoadDepartments(IAsyncResult result)
		{
			Action<IAsyncResult> andLoad = Context.EndLoadProperty;
			Dispatcher.Invoke(andLoad, DispatcherPriority.Normal, result);
			IsDepartmentLoad = false;
			RisePropertyChanged("IsDepartmentLoad");
		}

        #region Parent override

        public override void Dispose()
        {
        }

        public override bool CanCommit()
        {
            if (EditableItem == null) return false;
            return !string.IsNullOrEmpty(EditableItem.Name);
        }

        public override void Commit()
        {
			foreach (Department department in EditableItem.Department)
        	{
				if(department.Id != 0)
        			Context.UpdateObject(department);
        	}

        	base.Commit();
        }

        #endregion
    }
}
